package com.zyl.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhaoyl
 * @date 2024/5/20 21:58
 * @description 说明
 * 概念
 * 独享锁/共享锁
 * 独享锁是指该锁一次只能被一个线程所持有。
 * 共享锁是指该锁可被多个线程所持有。
 *
 * 对于Java ReentrantLock而言，其是独享锁。但是对于Lock的另一个实现类ReadWriteLock，其读锁是共享锁，其写锁是独享锁。
 * 读锁的共享锁可保证并发读是非常高效的，读写，写读 ，写写的过程是互斥的。
 * 独享锁与共享锁也是通过AQS来实现的，通过实现不同的方法，来实现独享或者共享。
 * 对于Synchronized而言，当然是独享锁。
 *
 * 互斥锁/读写锁
 * 上面讲的独享锁/共享锁就是一种广义的说法，互斥锁/读写锁就是具体的实现。
 * 互斥锁在Java中的具体实现就是ReentrantLock
 * 读写锁在Java中的具体实现就是ReadWriteLock
 */
public class Demo02 {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();
        new Thread(() -> {
            phone.sms();
        }, "线程A").start();
        new Thread(() -> {
            phone.sms();
        }, "线程B").start();
    }
}
    class Phone2 {
    Lock lock = new ReentrantLock();
        //加锁：可重入锁
        public  void sms() {
            lock.lock();//lock锁必须配对，否则会死锁
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "=>sms");
                //如果不是可重入锁的话，call()可能不会被当前线程执行，可能造成死锁。
                call();//这里也有锁（自动获取）
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
                lock.unlock();//配对
            }
        }

        public  void call() {
            lock.lock();
            try {
            System.out.println(Thread.currentThread().getName() + "=>call");
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }


